package cn.edu.seu.java.ast.visitor;

import java.io.File;
import java.util.LinkedList;
import java.util.List;

import org.eclipse.jdt.core.dom.ASTVisitor;
import org.eclipse.jdt.core.dom.CompilationUnit;
import org.eclipse.jdt.core.dom.MethodDeclaration;
import cn.edu.seu.java.node.ASTClass;

import cn.edu.seu.java.node.ASTMethod;
import cn.edu.seu.java.util.ASTNodeUtil;

public class ASTMethodVisitor extends ASTVisitor {
	private String sourceFilePath;
	private String projectName;
	private String versionNum;
	private LinkedList<ASTMethod> listOfASTMethod;
	private String packageName;
	private String versionPath;
	private String relativeSourceFilePath;

	public ASTMethodVisitor(List<CompilationUnit> unitList) {
		this.listOfASTMethod = new LinkedList<ASTMethod>();
		for (CompilationUnit unit : unitList) {
			this.projectName = (String) unit.getProperty("projectName");
			this.versionNum = (String) unit.getProperty("versionNum");
			this.versionPath = (String) unit.getProperty("versionPath");
			this.sourceFilePath = (String) unit.getProperty("sourceFilePath");
			this.relativeSourceFilePath = (String) unit.getProperty("relativeSourceFilePath");
			this.packageName = (String) unit.getProperty("packageName");
			
			unit.accept(this);
		}
	}

	public ASTMethodVisitor(CompilationUnit unit) {
		this.listOfASTMethod = new LinkedList<ASTMethod>();
		
		this.projectName =  (String) unit.getProperty("projectName");
		this.versionNum = (String) unit.getProperty("versionNum");
		this.versionPath = (String) unit.getProperty("versionPath");
		this.sourceFilePath = (String) unit.getProperty("sourceFilePath");
		this.relativeSourceFilePath = (String) unit.getProperty("relativeSourceFilePath");
		this.packageName = (String) unit.getProperty("packageName");
		
		unit.accept(this);
	}

	public ASTMethodVisitor(ASTClass classNode) {
		this.listOfASTMethod = new LinkedList<ASTMethod>();
		this.projectName = classNode.getProjectName();
		this.versionNum = classNode.getVersionNum();
		this.versionPath = classNode.getVersionPath();
		this.packageName = classNode.getPackageName();
		this.sourceFilePath = classNode.getSourceFilePath();
		this.relativeSourceFilePath = classNode.getRelativeSourceFilePath();
		classNode.getTypeDeclaration().accept(this);
	}

	/**
	 * extract all ASTMethods which are not nested in local class, enum class and anonymous class
	 */
	@Override
	public boolean visit(MethodDeclaration node) {
		if (ASTNodeUtil.isInLocalClass(node) != true && ASTNodeUtil.isInEnumClass(node) != true) {
			ASTMethod methodNode = new ASTMethod(packageName, sourceFilePath, node);
			methodNode.setProjectName(projectName);
			methodNode.setVersionNum(versionNum);
			methodNode.setVersionPath(versionPath);
			methodNode.setRelativeSourcePath(this.relativeSourceFilePath);
			methodNode.setFullyQualifiedTopClassName(ASTNodeUtil.getFullyQualifiedTopClassName(node));
			this.listOfASTMethod.add(methodNode);
		}
		return true;
	}

	/**
	 * 
	 * @return extract all ASTMethods which are not nested in local class, enum class and anonymous class
	 * 
	 */
	public List<ASTMethod> getASTMethodsNotEnclosedInLocalClassAndEnumClassAndAnonymousClass() {
		return this.listOfASTMethod;
	}
}
